'''
##一  作用域
>python 的只有在 moudlue class and func 中才会产生 作用域

```
作用域法则   L_E_G_B
Built-in
    Global
        enclosing
            local
```
```python
x=10                   #-----G
def fun():              
    a=5                #-----E
    def inner():
        count=7        #-----L
        print(a)
        return 1
```
>在 if-elif-else 、 for-else、try..catch\try..finnally 中 不会产生作用域
```python
if True:
    variable =100
print('*******')
print variable
```

##二  高阶函数
> 函数名可以作为参数输入  or 函数名可以作为返回值

##三  闭包
> 定义：如果一个内部函数里，在对外部作用域的变量进行引用，那么内部函数被认为是闭包
   闭包是一种现象 或者 是一个满足这两个条件的函数
```python
def outer():
    x=10
    def inner():
        print(x)
    return inner
```

```python
def outer():
    x=10
    def inner():
        global x
        x=11    #想修改外部的变量，需要在自己作用域声明 使用的是外部的变量
        print(x)
    return inner
```
##四 装饰器
```python

```
'''
import time

def func():
    print('func: do something...')

# add calculate time for  func
def funcCalcTime():
    start_time=time.time()
    print('funcCalcTime:do something...')
    time.sleep(1)
    time_span = time.time()-start_time
    print('spend %s'% time_span)

funcCalcTime()

# add calculate time for  func with  design mode : close for modify,open for extend
def Calctime(somefunc):
    start_time=time.time()
    somefunc()
    time_span = time.time()-start_time
    print('spend %s'% time_span)

    
#无法做到向前兼容，因为改变了函数的调用，本来是调用func的，但是现在改为调用Calctime 了.
#Calctime(func)
'''
内部实现应该改为
func=Calctime(func)
func() #err---
'''
print('===================')

def Calctime2(somefunc):
    def inner():
        start_time=time.time()
        somefunc()
        time_span = time.time()-start_time
        print('spend %s'% time_span)
    return inner

func=Calctime2(func)
func()
print('===================')
# 装饰器就是在现有的函数上增加额外的功能
@Calctime2
def bar():
    print('bar: balala')
    
bar()

# ======  延伸一 有参功能函数
def printable(somefunc):
    def inner(*a):
       print(somefunc(*a)) 
    return inner

@printable
def func3(*a):
    sums=0
    for i in a:
        sums+=i
    return sums
print('===================')
func3(1,3,4)
# ======== 延伸二 多个装饰器？
print('===================')

def logger(somefunc):
    name=somefunc.__name__
    def inner():
        print('start enter..%s' % name)
        somefunc()
        print('leave ...' )
    return inner

@logger #lala=logger(lala)
@Calctime2 #lala=Calctime2(lala)
def lala():
    print('multi func: lala')
lala()


#==========带参数的装饰器函数
print('===================')
def isPrintResult(isPrint):
    
    def Calctime2(somefunc):
        def inner():
            start_time=time.time()
            somefunc()
            time_span = time.time()-start_time
            if isPrint=='True':
                print('True--spend %s'% time_span)
            else:
                print('False--spend %s'% time_span)
        return inner
    return Calctime2
@isPrintResult('False')
def lala2():
    print('multi func: lala2')
lala2()
  